<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="language" content="en" />
        <link href="./assets/ffd55088/css/bootstrap.css" rel="stylesheet">
<link href="./assets/5cf9384a/solarized_light.css" rel="stylesheet">
<link href="./assets/6c54116e/style.css" rel="stylesheet">
<script src="./assets/a44cef0f/jquery.js"></script>
<script src="./assets/ffd55088/js/bootstrap.js"></script>
<script src="./assets/8ac4e28a/jssearch.js"></script>    <title>Authorization - Security - The Definitive Guide to Yii 2.0</title>
</head>
<body>

<div class="wrap">
    <nav id="w1783" class="navbar-inverse navbar-fixed-top navbar" role="navigation"><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#w1783-collapse"><span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span></button><a class="navbar-brand" href="./index.html">The Definitive Guide to Yii 2.0</a></div><div id="w1783-collapse" class="collapse navbar-collapse"><ul id="w1784" class="navbar-nav nav"><li><a href="./index.html">Class reference</a></li>
<li class="dropdown"><a class="dropdown-toggle" href="#" data-toggle="dropdown">Extensions <b class="caret"></b></a><ul id="w1785" class="dropdown-menu"><li><a href="./ext-apidoc-index.html" tabindex="-1">apidoc</a></li>
<li><a href="./ext-authclient-index.html" tabindex="-1">authclient</a></li>
<li><a href="./ext-bootstrap-index.html" tabindex="-1">bootstrap</a></li>
<li><a href="./ext-codeception-index.html" tabindex="-1">codeception</a></li>
<li><a href="./ext-debug-index.html" tabindex="-1">debug</a></li>
<li><a href="./ext-elasticsearch-index.html" tabindex="-1">elasticsearch</a></li>
<li><a href="./ext-faker-index.html" tabindex="-1">faker</a></li>
<li><a href="./ext-gii-index.html" tabindex="-1">gii</a></li>
<li><a href="./ext-imagine-index.html" tabindex="-1">imagine</a></li>
<li><a href="./ext-jui-index.html" tabindex="-1">jui</a></li>
<li><a href="./ext-mongodb-index.html" tabindex="-1">mongodb</a></li>
<li><a href="./ext-redis-index.html" tabindex="-1">redis</a></li>
<li><a href="./ext-smarty-index.html" tabindex="-1">smarty</a></li>
<li><a href="./ext-sphinx-index.html" tabindex="-1">sphinx</a></li>
<li><a href="./ext-swiftmailer-index.html" tabindex="-1">swiftmailer</a></li>
<li><a href="./ext-twig-index.html" tabindex="-1">twig</a></li></ul></li>
<li><a href="./guide-README.html">Guide</a></li></ul><div class="navbar-form navbar-left" role="search">
  <div class="form-group">
    <input id="searchbox" type="text" class="form-control" placeholder="Search">
  </div>
</div>
</div></nav>
    <div id="search-resultbox" style="display: none;" class="modal-content">
        <ul id="search-results">
        </ul>
    </div>

    
<div class="row">
    <div class="col-md-2">
                <div id="navigation" class="list-group"><a class="list-group-item" href="#navigation-1767" data-toggle="collapse" data-parent="#navigation">Introduction <b class="caret"></b></a><div id="navigation-1767" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-intro-yii.html">About Yii</a>
<a class="list-group-item" href="./guide-intro-upgrade-from-v1.html">Upgrading from Version 1.1</a></div>
<a class="list-group-item" href="#navigation-1768" data-toggle="collapse" data-parent="#navigation">Getting Started <b class="caret"></b></a><div id="navigation-1768" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-start-installation.html">Installing Yii</a>
<a class="list-group-item" href="./guide-start-workflow.html">Running Applications</a>
<a class="list-group-item" href="./guide-start-hello.html">Saying Hello</a>
<a class="list-group-item" href="./guide-start-forms.html">Working with Forms</a>
<a class="list-group-item" href="./guide-start-databases.html">Working with Databases</a>
<a class="list-group-item" href="./guide-start-gii.html">Generating Code with Gii</a>
<a class="list-group-item" href="./guide-start-looking-ahead.html">Looking Ahead</a></div>
<a class="list-group-item" href="#navigation-1769" data-toggle="collapse" data-parent="#navigation">Application Structure <b class="caret"></b></a><div id="navigation-1769" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-structure-overview.html">Overview</a>
<a class="list-group-item" href="./guide-structure-entry-scripts.html">Entry Scripts</a>
<a class="list-group-item" href="./guide-structure-applications.html">Applications</a>
<a class="list-group-item" href="./guide-structure-application-components.html">Application Components</a>
<a class="list-group-item" href="./guide-structure-controllers.html">Controllers</a>
<a class="list-group-item" href="./guide-structure-models.html">Models</a>
<a class="list-group-item" href="./guide-structure-views.html">Views</a>
<a class="list-group-item" href="./guide-structure-modules.html">Modules</a>
<a class="list-group-item" href="./guide-structure-filters.html">Filters</a>
<a class="list-group-item" href="./guide-structure-widgets.html">Widgets</a>
<a class="list-group-item" href="./guide-structure-assets.html">Assets</a>
<a class="list-group-item" href="./guide-structure-extensions.html">Extensions</a></div>
<a class="list-group-item" href="#navigation-1770" data-toggle="collapse" data-parent="#navigation">Handling Requests <b class="caret"></b></a><div id="navigation-1770" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-runtime-overview.html">Overview</a>
<a class="list-group-item" href="./guide-runtime-bootstrapping.html">Bootstrapping</a>
<a class="list-group-item" href="./guide-runtime-routing.html">Routing and URL Creation</a>
<a class="list-group-item" href="./guide-runtime-requests.html">Requests</a>
<a class="list-group-item" href="./guide-runtime-responses.html">Responses</a>
<a class="list-group-item" href="./guide-runtime-sessions-cookies.html">Sessions and Cookies</a>
<a class="list-group-item" href="./guide-runtime-handling-errors.html">Handling Errors</a>
<a class="list-group-item" href="./guide-runtime-logging.html">Logging</a></div>
<a class="list-group-item" href="#navigation-1771" data-toggle="collapse" data-parent="#navigation">Key Concepts <b class="caret"></b></a><div id="navigation-1771" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-concept-components.html">Components</a>
<a class="list-group-item" href="./guide-concept-properties.html">Properties</a>
<a class="list-group-item" href="./guide-concept-events.html">Events</a>
<a class="list-group-item" href="./guide-concept-behaviors.html">Behaviors</a>
<a class="list-group-item" href="./guide-concept-configurations.html">Configurations</a>
<a class="list-group-item" href="./guide-concept-aliases.html">Aliases</a>
<a class="list-group-item" href="./guide-concept-autoloading.html">Class Autoloading</a>
<a class="list-group-item" href="./guide-concept-service-locator.html">Service Locator</a>
<a class="list-group-item" href="./guide-concept-di-container.html">Dependency Injection Container</a></div>
<a class="list-group-item" href="#navigation-1772" data-toggle="collapse" data-parent="#navigation">Working with Databases <b class="caret"></b></a><div id="navigation-1772" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-db-dao.html">Data Access Objects</a>
<a class="list-group-item" href="./guide-db-query-builder.html">Query Builder</a>
<a class="list-group-item" href="./guide-db-active-record.html">Active Record</a>
<a class="list-group-item" href="./guide-db-migrations.html">Migrations</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md">Sphinx</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md">Redis</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md">MongoDB</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md">ElasticSearch</a></div>
<a class="list-group-item" href="#navigation-1773" data-toggle="collapse" data-parent="#navigation">Getting Data from Users <b class="caret"></b></a><div id="navigation-1773" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-input-forms.html">Creating Forms</a>
<a class="list-group-item" href="./guide-input-validation.html">Validating Input</a>
<a class="list-group-item" href="./guide-input-file-upload.html">Uploading Files</a>
<a class="list-group-item" href="./guide-input-tabular-input.html">Collecting Tabular Input</a>
<a class="list-group-item" href="./guide-input-multiple-models.html">Getting Data for Multiple Models</a></div>
<a class="list-group-item" href="#navigation-1774" data-toggle="collapse" data-parent="#navigation">Displaying Data <b class="caret"></b></a><div id="navigation-1774" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-output-formatting.html">Data Formatting</a>
<a class="list-group-item" href="./guide-output-pagination.html">Pagination</a>
<a class="list-group-item" href="./guide-output-sorting.html">Sorting</a>
<a class="list-group-item" href="./guide-output-data-providers.html">Data Providers</a>
<a class="list-group-item" href="./guide-output-data-widgets.html">Data Widgets</a>
<a class="list-group-item" href="./guide-output-client-scripts.html">Working with Client Scripts</a>
<a class="list-group-item" href="./guide-output-theming.html">Theming</a></div>
<a class="list-group-item active" href="#navigation-1775" data-toggle="collapse" data-parent="#navigation">Security <b class="caret"></b></a><div id="navigation-1775" class="submenu panel-collapse collapse in"><a class="list-group-item" href="./guide-security-overview.html">Overview</a>
<a class="list-group-item" href="./guide-security-authentication.html">Authentication</a>
<a class="list-group-item active" href="./guide-security-authorization.html">Authorization</a>
<a class="list-group-item" href="./guide-security-passwords.html">Working with Passwords</a>
<a class="list-group-item" href="./guide-security-cryptography.html">Cryptography</a>
<a class="list-group-item" href="./guide-structure-views.html#security">Views security</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md">Auth Clients</a>
<a class="list-group-item" href="./guide-security-best-practices.html">Best Practices</a></div>
<a class="list-group-item" href="#navigation-1776" data-toggle="collapse" data-parent="#navigation">Caching <b class="caret"></b></a><div id="navigation-1776" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-caching-overview.html">Overview</a>
<a class="list-group-item" href="./guide-caching-data.html">Data Caching</a>
<a class="list-group-item" href="./guide-caching-fragment.html">Fragment Caching</a>
<a class="list-group-item" href="./guide-caching-page.html">Page Caching</a>
<a class="list-group-item" href="./guide-caching-http.html">HTTP Caching</a></div>
<a class="list-group-item" href="#navigation-1777" data-toggle="collapse" data-parent="#navigation">RESTful Web Services <b class="caret"></b></a><div id="navigation-1777" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-rest-quick-start.html">Quick Start</a>
<a class="list-group-item" href="./guide-rest-resources.html">Resources</a>
<a class="list-group-item" href="./guide-rest-controllers.html">Controllers</a>
<a class="list-group-item" href="./guide-rest-routing.html">Routing</a>
<a class="list-group-item" href="./guide-rest-response-formatting.html">Response Formatting</a>
<a class="list-group-item" href="./guide-rest-authentication.html">Authentication</a>
<a class="list-group-item" href="./guide-rest-rate-limiting.html">Rate Limiting</a>
<a class="list-group-item" href="./guide-rest-versioning.html">Versioning</a>
<a class="list-group-item" href="./guide-rest-error-handling.html">Error Handling</a></div>
<a class="list-group-item" href="#navigation-1778" data-toggle="collapse" data-parent="#navigation">Development Tools <b class="caret"></b></a><div id="navigation-1778" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md">Debug Toolbar and Debugger</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md">Generating Code using Gii</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-apidoc">Generating API Documentation</a></div>
<a class="list-group-item" href="#navigation-1779" data-toggle="collapse" data-parent="#navigation">Testing <b class="caret"></b></a><div id="navigation-1779" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-test-overview.html">Overview</a>
<a class="list-group-item" href="./guide-test-environment-setup.html">Testing environment setup</a>
<a class="list-group-item" href="./guide-test-unit.html">Unit Tests</a>
<a class="list-group-item" href="./guide-test-functional.html">Functional Tests</a>
<a class="list-group-item" href="./guide-test-acceptance.html">Acceptance Tests</a>
<a class="list-group-item" href="./guide-test-fixtures.html">Fixtures</a></div>
<a class="list-group-item" href="#navigation-1780" data-toggle="collapse" data-parent="#navigation">Special Topics <b class="caret"></b></a><div id="navigation-1780" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>
<a class="list-group-item" href="./guide-tutorial-start-from-scratch.html">Building Application from Scratch</a>
<a class="list-group-item" href="./guide-tutorial-console.html">Console Commands</a>
<a class="list-group-item" href="./guide-tutorial-core-validators.html">Core Validators</a>
<a class="list-group-item" href="./guide-tutorial-i18n.html">Internationalization</a>
<a class="list-group-item" href="./guide-tutorial-mailing.html">Mailing</a>
<a class="list-group-item" href="./guide-tutorial-performance-tuning.html">Performance Tuning</a>
<a class="list-group-item" href="./guide-tutorial-shared-hosting.html">Shared Hosting Environment</a>
<a class="list-group-item" href="./guide-tutorial-template-engines.html">Template Engines</a>
<a class="list-group-item" href="./guide-tutorial-yii-integration.html">Working with Third-Party Code</a></div>
<a class="list-group-item" href="#navigation-1781" data-toggle="collapse" data-parent="#navigation">Widgets <b class="caret"></b></a><div id="navigation-1781" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md">Bootstrap Widgets</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md">jQuery UI Widgets</a></div>
<a class="list-group-item" href="#navigation-1782" data-toggle="collapse" data-parent="#navigation">Helpers <b class="caret"></b></a><div id="navigation-1782" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-helper-overview.html">Overview</a>
<a class="list-group-item" href="./guide-helper-array.html">ArrayHelper</a>
<a class="list-group-item" href="./guide-helper-html.html">Html</a>
<a class="list-group-item" href="./guide-helper-url.html">Url</a></div></div>    </div>
    <div class="col-md-9 guide-content" role="main">
        <h1>Authorization <span id="authorization"></span><a href="#authorization" class="hashlink">&para;</a></h1>
<div class="toc"><ol><li><a href="#access-control-filter">Access Control Filter</a></li>
<li><a href="#rbac">Role Based Access Control (RBAC)</a></li></ol></div>
<p>Authorization is the process of verifying that a user has enough permission to do something. Yii provides two authorization
methods: Access Control Filter (ACF) and Role-Based Access Control (RBAC).</p>
<h2>Access Control Filter  <span id="access-control-filter"></span><a href="#access-control-filter" class="hashlink">&para;</a></h2><p>Access Control Filter (ACF) is a simple authorization method implemented as <a href="./yii-filters-accesscontrol.html">yii\filters\AccessControl</a> which
is best used by applications that only need some simple access control. As its name indicates, ACF is 
an action <a href="guide-structure-filters.html">filter</a> that can be used in a controller or a module. While a user is requesting
to execute an action, ACF will check a list of <a href="./yii-filters-accesscontrol.html#$rules-detail">access rules</a> 
to determine if the user is allowed to access the requested action.</p>
<p>The code below shows how to use ACF in the <code>site</code> controller:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">web</span>\<span class="hljs-title">Controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">filters</span>\<span class="hljs-title">AccessControl</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SiteController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">behaviors</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-string">'access'</span> =&gt; [
                <span class="hljs-string">'class'</span> =&gt; AccessControl::className(),
                <span class="hljs-string">'only'</span> =&gt; [<span class="hljs-string">'login'</span>, <span class="hljs-string">'logout'</span>, <span class="hljs-string">'signup'</span>],
                <span class="hljs-string">'rules'</span> =&gt; [
                    [
                        <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                        <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'login'</span>, <span class="hljs-string">'signup'</span>],
                        <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'?'</span>],
                    ],
                    [
                        <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                        <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'logout'</span>],
                        <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'@'</span>],
                    ],
                ],
            ],
        ];
    }
    <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>In the code above ACF is attached to the <code>site</code> controller as a behavior. This is the typical way of using an action
filter. The <code>only</code> option specifies that the ACF should only be applied to the <code>login</code>, <code>logout</code> and <code>signup</code> actions.
All other actions in the <code>site</code> controller are not subject to the access control. The <code>rules</code> option lists 
the <a href="./yii-filters-accessrule.html">access rules</a>, which reads as follows:</p>
<ul>
<li>Allow all guest (not yet authenticated) users to access the <code>login</code> and <code>signup</code> actions. The <code>roles</code> option
contains a question mark <code>?</code> which is a special token representing "guest users".</li>
<li>Allow authenticated users to access the <code>logout</code> action. The <code>@</code> character is another special token representing
"authenticated users".</li>
</ul>
<p>ACF performs the authorization check by examining the access rules one by one from top to bottom until it finds
a rule that matches the current execution context. The <code>allow</code> value of the matching rule will then be used to 
judge if the user is authorized or not. If none of the rules matches, it means the user is NOT authorized,
and ACF will stop further action execution.</p>
<p>When ACF determines a user is not authorized to access the current action, it takes the following measure by default:</p>
<ul>
<li>If the user is a guest, it will call <a href="./yii-web-user.html#loginRequired()-detail">yii\web\User::loginRequired()</a> to redirect the user browser to the login page.</li>
<li>If the user is already authenticated, it will throw a <a href="./yii-web-forbiddenhttpexception.html">yii\web\ForbiddenHttpException</a>.</li>
</ul>
<p>You may customize this behavior by configuring the <a href="./yii-filters-accesscontrol.html#$denyCallback-detail">yii\filters\AccessControl::$denyCallback</a> property like the following:</p>
<pre><code class="hljs php language-php">[
    <span class="hljs-string">'class'</span> =&gt; AccessControl::className(),
    ...
    <span class="hljs-string">'denyCallback'</span> =&gt; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$rule</span>, <span class="hljs-variable">$action</span>)</span> </span>{
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> \<span class="hljs-keyword">Exception</span>(<span class="hljs-string">'You are not allowed to access this page'</span>);
    }
]
</code></pre>
<p><a href="./yii-filters-accessrule.html">Access rules</a> support many options. Below is a summary of the supported options.
You may also extend <a href="./yii-filters-accessrule.html">yii\filters\AccessRule</a> to create your own customized access rule classes.</p>
<ul>
<li><p><a href="./yii-filters-accessrule.html#$allow-detail">allow</a>: specifies whether this is an "allow" or "deny" rule.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$actions-detail">actions</a>: specifies which actions this rule matches. This should
be an array of action IDs. The comparison is case-sensitive. If this option is empty or not set,
it means the rule applies to all actions.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$controllers-detail">controllers</a>: specifies which controllers this rule
matches. This should be an array of controller IDs. Each controller ID is prefixed with the module ID (if any).
The comparison is case-sensitive. If this option is empty or not set, it means the rule applies to all controllers.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$roles-detail">roles</a>: specifies which user roles that this rule matches.
Two special roles are recognized, and they are checked via <a href="./yii-web-user.html#$isGuest-detail">yii\web\User::$isGuest</a>:</p>
<ul>
<li><code>?</code>: matches a guest user (not authenticated yet)</li>
<li><code>@</code>: matches an authenticated user</li>
</ul>
<p>Using other role names will trigger the invocation of <a href="./yii-web-user.html#can()-detail">yii\web\User::can()</a>, which requires enabling RBAC 
(to be described in the next subsection). If this option is empty or not set, it means this rule applies to all roles.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$ips-detail">ips</a>: specifies which <a href="./yii-web-request.html#$userIP-detail">client IP addresses</a> this rule matches.
An IP address can contain the wildcard <code>*</code> at the end so that it matches IP addresses with the same prefix.
For example, '192.168.*' matches all IP addresses in the segment '192.168.'. If this option is empty or not set,
it means this rule applies to all IP addresses.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$verbs-detail">verbs</a>: specifies which request method (e.g. <code>GET</code>, <code>POST</code>) this rule matches.
The comparison is case-insensitive.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$matchCallback-detail">matchCallback</a>: specifies a PHP callable that should be called to determine
if this rule should be applied.</p>
</li>
<li><p><a href="./yii-filters-accessrule.html#$denyCallback-detail">denyCallback</a>: specifies a PHP callable that should be called when this rule
will deny the access.</p>
</li>
</ul>
<p>Below is an example showing how to make use of the <code>matchCallback</code> option, which allows you to write arbitrary access
check logic:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">filters</span>\<span class="hljs-title">AccessControl</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SiteController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">behaviors</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-string">'access'</span> =&gt; [
                <span class="hljs-string">'class'</span> =&gt; AccessControl::className(),
                <span class="hljs-string">'only'</span> =&gt; [<span class="hljs-string">'special-callback'</span>],
                <span class="hljs-string">'rules'</span> =&gt; [
                    [
                        <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'special-callback'</span>],
                        <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                        <span class="hljs-string">'matchCallback'</span> =&gt; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$rule</span>, <span class="hljs-variable">$action</span>)</span> </span>{
                            <span class="hljs-keyword">return</span> date(<span class="hljs-string">'d-m'</span>) === <span class="hljs-string">'31-10'</span>;
                        }
                    ],
                ],
            ],
        ];
    }

    <span class="hljs-comment">// Match callback called! This page can be accessed only each October 31st</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">actionSpecialCallback</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-variable">$this</span>-&gt;render(<span class="hljs-string">'happy-halloween'</span>);
    }
}
</code></pre>
<h2>Role Based Access Control (RBAC)  <span id="rbac"></span><a href="#rbac" class="hashlink">&para;</a></h2><p>Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to
the <a href="http://en.wikipedia.org/wiki/Role-based_access_control">Wikipedia</a> for details about comparing RBAC
with other more traditional access control schemes.</p>
<p>Yii implements a General Hierarchical RBAC, following the <a href="http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf">NIST RBAC model</a>.
It provides the RBAC functionality through the <a href="./yii-rbac-managerinterface.html">authManager</a> <a href="guide-structure-application-components.html">application component</a>.</p>
<p>Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second
part is to use the authorization data to perform access check in places where it is needed.</p>
<p>To facilitate our description next, we will first introduce some basic RBAC concepts.</p>
<h3>Basic Concepts  <span id="basic-concepts"></span><a href="#basic-concepts" class="hashlink">&para;</a></h3><p>A role represents a collection of <em>permissions</em> (e.g. creating posts, updating posts). A role may be assigned
to one or multiple users. To check if a user has a specified permission, we may check if the user is assigned
with a role that contains that permission.</p>
<p>Associated with each role or permission, there may be a <em>rule</em>. A rule represents a piece of code that will be
executed during access check to determine if the corresponding role or permission applies to the current user.
For example, the "update post" permission may have a rule that checks if the current user is the post creator.
During access checking, if the user is NOT the post creator, he/she will be considered not having the "update post" permission.</p>
<p>Both roles and permissions can be organized in a hierarchy. In particular, a role may consist of other roles or permissions;
and a permission may consist of other permissions. Yii implements a <em>partial order</em> hierarchy which includes the
more special <em>tree</em> hierarchy. While a role can contain a permission, it is not true vice versa.</p>
<h3>Configuring RBAC  <span id="configuring-rbac"></span><a href="#configuring-rbac" class="hashlink">&para;</a></h3><p>Before we set off to define authorization data and perform access checking, we need to configure the
<a href="./yii-base-application.html#$authManager-detail">authManager</a> application component. Yii provides two types of authorization managers:
<a href="./yii-rbac-phpmanager.html">yii\rbac\PhpManager</a> and <a href="./yii-rbac-dbmanager.html">yii\rbac\DbManager</a>. The former uses a PHP script file to store authorization
data, while the latter stores authorization data in a database. You may consider using the former if your application
does not require very dynamic role and permission management.</p>
<h4>Using <code>PhpManager</code>  <span id="using-php-manager"></span><a href="#using-php-manager" class="hashlink">&para;</a></h4><p>The following code shows how to configure the <code>authManager</code> in the application configuration using the <a href="./yii-rbac-phpmanager.html">yii\rbac\PhpManager</a> class:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">return</span> [
    <span class="hljs-comment">// ...</span>
    <span class="hljs-string">'components'</span> =&gt; [
        <span class="hljs-string">'authManager'</span> =&gt; [
            <span class="hljs-string">'class'</span> =&gt; <span class="hljs-string">'yii\rbac\PhpManager'</span>,
        ],
        <span class="hljs-comment">// ...</span>
    ],
];
</code></pre>
<p>The <code>authManager</code> can now be accessed via <code>\Yii::$app-&gt;authManager</code>.</p>
<p>By default, <a href="./yii-rbac-phpmanager.html">yii\rbac\PhpManager</a> stores RBAC data in files under <code>@app/rbac</code> directory. Make sure the directory
and all the files in it are writable by the Web server process if permissions hierarchy needs to be changed online.</p>
<h4>Using <code>DbManager</code>  <span id="using-db-manager"></span><a href="#using-db-manager" class="hashlink">&para;</a></h4><p>The following code shows how to configure the <code>authManager</code> in the application configuration using the <a href="./yii-rbac-dbmanager.html">yii\rbac\DbManager</a> class:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">return</span> [
    <span class="hljs-comment">// ...</span>
    <span class="hljs-string">'components'</span> =&gt; [
        <span class="hljs-string">'authManager'</span> =&gt; [
            <span class="hljs-string">'class'</span> =&gt; <span class="hljs-string">'yii\rbac\DbManager'</span>,
        ],
        <span class="hljs-comment">// ...</span>
    ],
];
</code></pre>
<blockquote class="note"><p><strong>Note: </strong>If you are using yii2-basic-app template, there is a <code>config/console.php</code> configuration file where the
  <code>authManager</code> needs to be declared additionally to <code>config/web.php</code>.
In case of yii2-advanced-app the <code>authManager</code> should be declared only once in <code>common/config/main.php</code>.</p>
</blockquote>
<p><code>DbManager</code> uses four database tables to store its data: </p>
<ul>
<li><a href="./yii-rbac-dbmanager.html#$itemTable-detail">itemTable</a>: the table for storing authorization items. Defaults to "auth_item".</li>
<li><a href="./yii-rbac-dbmanager.html#$itemChildTable-detail">itemChildTable</a>: the table for storing authorization item hierarchy. Defaults to "auth_item_child".</li>
<li><a href="./yii-rbac-dbmanager.html#$assignmentTable-detail">assignmentTable</a>: the table for storing authorization item assignments. Defaults to "auth_assignment".</li>
<li><a href="./yii-rbac-dbmanager.html#$ruleTable-detail">ruleTable</a>: the table for storing rules. Defaults to "auth_rule".</li>
</ul>
<p>Before you can go on you need to create those tables in the database. To do this, you can use the migration stored in <code>@yii/rbac/migrations</code>:</p>
<p><code>yii migrate --migrationPath=@yii/rbac/migrations</code></p>
<p>The <code>authManager</code> can now be accessed via <code>\Yii::$app-&gt;authManager</code>.</p>
<h3>Building Authorization Data  <span id="generating-rbac-data"></span><a href="#generating-rbac-data" class="hashlink">&para;</a></h3><p>Building authorization data is all about the following tasks:</p>
<ul>
<li>defining roles and permissions;</li>
<li>establishing relations among roles and permissions;</li>
<li>defining rules;</li>
<li>associating rules with roles and permissions;</li>
<li>assigning roles to users.</li>
</ul>
<p>Depending on authorization flexibility requirements the tasks above could be done in different ways.</p>
<p>If your permissions hierarchy doesn't change at all and you have a fixed number of users you can create a
<a href="guide-tutorial-console.html#create-command">console command</a> that will initialize authorization data once via APIs offered by <code>authManager</code>:</p>
<pre><code class="hljs php language-php"><span class="hljs-preprocessor">&lt;?php</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">commands</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Yii</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">console</span>\<span class="hljs-title">Controller</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RbacController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">actionInit</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-variable">$auth</span> = Yii::<span class="hljs-variable">$app</span>-&gt;authManager;

        <span class="hljs-comment">// add "createPost" permission</span>
        <span class="hljs-variable">$createPost</span> = <span class="hljs-variable">$auth</span>-&gt;createPermission(<span class="hljs-string">'createPost'</span>);
        <span class="hljs-variable">$createPost</span>-&gt;description = <span class="hljs-string">'Create a post'</span>;
        <span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$createPost</span>);

        <span class="hljs-comment">// add "updatePost" permission</span>
        <span class="hljs-variable">$updatePost</span> = <span class="hljs-variable">$auth</span>-&gt;createPermission(<span class="hljs-string">'updatePost'</span>);
        <span class="hljs-variable">$updatePost</span>-&gt;description = <span class="hljs-string">'Update post'</span>;
        <span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$updatePost</span>);

        <span class="hljs-comment">// add "author" role and give this role the "createPost" permission</span>
        <span class="hljs-variable">$author</span> = <span class="hljs-variable">$auth</span>-&gt;createRole(<span class="hljs-string">'author'</span>);
        <span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$author</span>);
        <span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$author</span>, <span class="hljs-variable">$createPost</span>);

        <span class="hljs-comment">// add "admin" role and give this role the "updatePost" permission</span>
        <span class="hljs-comment">// as well as the permissions of the "author" role</span>
        <span class="hljs-variable">$admin</span> = <span class="hljs-variable">$auth</span>-&gt;createRole(<span class="hljs-string">'admin'</span>);
        <span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$admin</span>);
        <span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$admin</span>, <span class="hljs-variable">$updatePost</span>);
        <span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$admin</span>, <span class="hljs-variable">$author</span>);

        <span class="hljs-comment">// Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()</span>
        <span class="hljs-comment">// usually implemented in your User model.</span>
        <span class="hljs-variable">$auth</span>-&gt;assign(<span class="hljs-variable">$author</span>, <span class="hljs-number">2</span>);
        <span class="hljs-variable">$auth</span>-&gt;assign(<span class="hljs-variable">$admin</span>, <span class="hljs-number">1</span>);
    }
}
</code></pre>
<blockquote class="note"><p><strong>Note: </strong>If you are using advanced template, you need to put your <code>RbacController</code> inside <code>console/controllers</code> directory
  and change namespace to <code>console/controllers</code>.</p>
</blockquote>
<p>After executing the command with <code>yii rbac/init</code> we'll get the following hierarchy:</p>
<p><img src="images/rbac-hierarchy-1.png" alt="Simple RBAC hierarchy" title="Simple RBAC hierarchy" /></p>
<p>Author can create post, admin can update post and do everything author can.</p>
<p>If your application allows user signup you need to assign roles to these new users once. For example, in order for all
signed up users to become authors in your advanced project template you need to modify <code>frontend\models\SignupForm::signup()</code>
as follows:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">signup</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-variable">$this</span>-&gt;validate()) {
        <span class="hljs-variable">$user</span> = <span class="hljs-keyword">new</span> User();
        <span class="hljs-variable">$user</span>-&gt;username = <span class="hljs-variable">$this</span>-&gt;username;
        <span class="hljs-variable">$user</span>-&gt;email = <span class="hljs-variable">$this</span>-&gt;email;
        <span class="hljs-variable">$user</span>-&gt;setPassword(<span class="hljs-variable">$this</span>-&gt;password);
        <span class="hljs-variable">$user</span>-&gt;generateAuthKey();
        <span class="hljs-variable">$user</span>-&gt;save(<span class="hljs-keyword">false</span>);

        <span class="hljs-comment">// the following three lines were added:</span>
        <span class="hljs-variable">$auth</span> = Yii::<span class="hljs-variable">$app</span>-&gt;authManager;
        <span class="hljs-variable">$authorRole</span> = <span class="hljs-variable">$auth</span>-&gt;getRole(<span class="hljs-string">'author'</span>);
        <span class="hljs-variable">$auth</span>-&gt;assign(<span class="hljs-variable">$authorRole</span>, <span class="hljs-variable">$user</span>-&gt;getId());

        <span class="hljs-keyword">return</span> <span class="hljs-variable">$user</span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
}
</code></pre>
<p>For applications that require complex access control with dynamically updated authorization data, special user interfaces
(i.e. admin panel) may need to be developed using APIs offered by <code>authManager</code>.</p>
<h3>Using Rules  <span id="using-rules"></span><a href="#using-rules" class="hashlink">&para;</a></h3><p>As aforementioned, rules add additional constraint to roles and permissions. A rule is a class extending
from <a href="./yii-rbac-rule.html">yii\rbac\Rule</a>. It must implement the <a href="./yii-rbac-rule.html#execute()-detail">execute()</a> method. In the hierarchy we've
created previously author cannot edit his own post. Let's fix it. First we need a rule to verify that the user is the post author:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">rbac</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">rbac</span>\<span class="hljs-title">Rule</span>;

<span class="hljs-comment">/**
 * Checks if authorID matches user passed via params
 */</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AuthorRule</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Rule</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$name</span> = <span class="hljs-string">'isAuthor'</span>;

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@param</span> string|integer $user the user ID.
     * <span class="hljs-doctag">@param</span> Item $item the role or permission that this rule is associated with
     * <span class="hljs-doctag">@param</span> array $params parameters passed to ManagerInterface::checkAccess().
     * <span class="hljs-doctag">@return</span> boolean a value indicating whether the rule permits the role or permission it is associated with.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span><span class="hljs-params">(<span class="hljs-variable">$user</span>, <span class="hljs-variable">$item</span>, <span class="hljs-variable">$params</span>)</span>
    </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$params</span>[<span class="hljs-string">'post'</span>]) ? <span class="hljs-variable">$params</span>[<span class="hljs-string">'post'</span>]-&gt;createdBy == <span class="hljs-variable">$user</span> : <span class="hljs-keyword">false</span>;
    }
}
</code></pre>
<p>The rule above checks if the <code>post</code> is created by <code>$user</code>. We'll create a special permission <code>updateOwnPost</code> in the
command we've used previously:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$auth</span> = Yii::<span class="hljs-variable">$app</span>-&gt;authManager;

<span class="hljs-comment">// add the rule</span>
<span class="hljs-variable">$rule</span> = <span class="hljs-keyword">new</span> \app\rbac\AuthorRule;
<span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$rule</span>);

<span class="hljs-comment">// add the "updateOwnPost" permission and associate the rule with it.</span>
<span class="hljs-variable">$updateOwnPost</span> = <span class="hljs-variable">$auth</span>-&gt;createPermission(<span class="hljs-string">'updateOwnPost'</span>);
<span class="hljs-variable">$updateOwnPost</span>-&gt;description = <span class="hljs-string">'Update own post'</span>;
<span class="hljs-variable">$updateOwnPost</span>-&gt;ruleName = <span class="hljs-variable">$rule</span>-&gt;name;
<span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$updateOwnPost</span>);

<span class="hljs-comment">// "updateOwnPost" will be used from "updatePost"</span>
<span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$updateOwnPost</span>, <span class="hljs-variable">$updatePost</span>);

<span class="hljs-comment">// allow "author" to update their own posts</span>
<span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$author</span>, <span class="hljs-variable">$updateOwnPost</span>);
</code></pre>
<p>Now we have got the following hierarchy:</p>
<p><img src="images/rbac-hierarchy-2.png" alt="RBAC hierarchy with a rule" title="RBAC hierarchy with a rule" /></p>
<h3>Access Check  <span id="access-check"></span><a href="#access-check" class="hashlink">&para;</a></h3><p>With the authorization data ready, access check is as simple as a call to the <a href="./yii-rbac-checkaccessinterface.html#checkAccess()-detail">yii\rbac\ManagerInterface::checkAccess()</a>
method. Because most access check is about the current user, for convenience Yii provides a shortcut method
<a href="./yii-web-user.html#can()-detail">yii\web\User::can()</a>, which can be used like the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">if</span> (\Yii::<span class="hljs-variable">$app</span>-&gt;user-&gt;can(<span class="hljs-string">'createPost'</span>)) {
    <span class="hljs-comment">// create post</span>
}
</code></pre>
<p>If the current user is Jane with <code>ID=1</code> we are starting at <code>createPost</code> and trying to get to <code>Jane</code>:</p>
<p><img src="images/rbac-access-check-1.png" alt="Access check" title="Access check" /></p>
<p>In order to check if a user can update a post, we need to pass an extra parameter that is required by <code>AuthorRule</code> described before:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">if</span> (\Yii::<span class="hljs-variable">$app</span>-&gt;user-&gt;can(<span class="hljs-string">'updatePost'</span>, [<span class="hljs-string">'post'</span> =&gt; <span class="hljs-variable">$post</span>])) {
    <span class="hljs-comment">// update post</span>
}
</code></pre>
<p>Here is what happens if the current user is John:</p>
<p><img src="images/rbac-access-check-2.png" alt="Access check" title="Access check" /></p>
<p>We are starting with the <code>updatePost</code> and going through <code>updateOwnPost</code>. In order to pass the access check, <code>AuthorRule</code> 
should return <code>true</code> from its <code>execute()</code> method. The method receives its <code>$params</code> from the <code>can()</code> method call so the value is
<code>['post' =&gt; $post]</code>. If everything is fine, we will get to <code>author</code> which is assigned to John.</p>
<p>In case of Jane it is a bit simpler since she is an admin:</p>
<p><img src="images/rbac-access-check-3.png" alt="Access check" title="Access check" /></p>
<p>Inside your controller there are a few ways to implement authorization. If you want granular permissions that
separate access to adding and deleting, then you need to check access for each action. You can either use the
above condition in each action method, or use <a href="./yii-filters-accesscontrol.html">yii\filters\AccessControl</a>:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">behaviors</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-string">'access'</span> =&gt; [
            <span class="hljs-string">'class'</span> =&gt; AccessControl::className(),
            <span class="hljs-string">'rules'</span> =&gt; [
                [
                    <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                    <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'index'</span>],
                    <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'managePost'</span>],
                ],
                [
                    <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                    <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'view'</span>],
                    <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'viewPost'</span>],
                ],
                [
                    <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                    <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'create'</span>],
                    <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'createPost'</span>],
                ],
                [
                    <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                    <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'update'</span>],
                    <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'updatePost'</span>],
                ],
                [
                    <span class="hljs-string">'allow'</span> =&gt; <span class="hljs-keyword">true</span>,
                    <span class="hljs-string">'actions'</span> =&gt; [<span class="hljs-string">'delete'</span>],
                    <span class="hljs-string">'roles'</span> =&gt; [<span class="hljs-string">'deletePost'</span>],
                ],
            ],
        ],
    ];
}
</code></pre>
<p>If all the CRUD operations are managed together then it's a good idea to use a single permission, like <code>managePost</code>, and
check it in <a href="./yii-web-controller.html#beforeAction()-detail">yii\web\Controller::beforeAction()</a>.</p>
<h3>Using Default Roles  <span id="using-default-roles"></span><a href="#using-default-roles" class="hashlink">&para;</a></h3><p>A default role is a role that is <em>implicitly</em> assigned to <em>all</em> users. The call to <a href="./yii-rbac-managerinterface.html#assign()-detail">yii\rbac\ManagerInterface::assign()</a>
is not needed, and the authorization data does not contain its assignment information.</p>
<p>A default role is usually associated with a rule which determines if the role applies to the user being checked.</p>
<p>Default roles are often used in applications which already have some sort of role assignment. For example, an application
may have a "group" column in its user table to represent which privilege group each user belongs to.
If each privilege group can be mapped to a RBAC role, you can use the default role feature to automatically
assign each user to a RBAC role. Let's use an example to show how this can be done.</p>
<p>Assume in the user table, you have a <code>group</code> column which uses 1 to represent the administrator group and 2 the author group.
You plan to have two RBAC roles <code>admin</code> and <code>author</code> to represent the permissions for these two groups, respectively.
You can set up the RBAC data as follows,</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">rbac</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Yii</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">rbac</span>\<span class="hljs-title">Rule</span>;

<span class="hljs-comment">/**
 * Checks if user group matches
 */</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserGroupRule</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Rule</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$name</span> = <span class="hljs-string">'userGroup'</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span><span class="hljs-params">(<span class="hljs-variable">$user</span>, <span class="hljs-variable">$item</span>, <span class="hljs-variable">$params</span>)</span>
    </span>{
        <span class="hljs-keyword">if</span> (!Yii::<span class="hljs-variable">$app</span>-&gt;user-&gt;isGuest) {
            <span class="hljs-variable">$group</span> = Yii::<span class="hljs-variable">$app</span>-&gt;user-&gt;identity-&gt;group;
            <span class="hljs-keyword">if</span> (<span class="hljs-variable">$item</span>-&gt;name === <span class="hljs-string">'admin'</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-variable">$group</span> == <span class="hljs-number">1</span>;
            } <span class="hljs-keyword">elseif</span> (<span class="hljs-variable">$item</span>-&gt;name === <span class="hljs-string">'author'</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-variable">$group</span> == <span class="hljs-number">1</span> || <span class="hljs-variable">$group</span> == <span class="hljs-number">2</span>;
            }
        }
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }
}

<span class="hljs-variable">$auth</span> = Yii::<span class="hljs-variable">$app</span>-&gt;authManager;

<span class="hljs-variable">$rule</span> = <span class="hljs-keyword">new</span> \app\rbac\UserGroupRule;
<span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$rule</span>);

<span class="hljs-variable">$author</span> = <span class="hljs-variable">$auth</span>-&gt;createRole(<span class="hljs-string">'author'</span>);
<span class="hljs-variable">$author</span>-&gt;ruleName = <span class="hljs-variable">$rule</span>-&gt;name;
<span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$author</span>);
<span class="hljs-comment">// ... add permissions as children of $author ...</span>

<span class="hljs-variable">$admin</span> = <span class="hljs-variable">$auth</span>-&gt;createRole(<span class="hljs-string">'admin'</span>);
<span class="hljs-variable">$admin</span>-&gt;ruleName = <span class="hljs-variable">$rule</span>-&gt;name;
<span class="hljs-variable">$auth</span>-&gt;add(<span class="hljs-variable">$admin</span>);
<span class="hljs-variable">$auth</span>-&gt;addChild(<span class="hljs-variable">$admin</span>, <span class="hljs-variable">$author</span>);
<span class="hljs-comment">// ... add permissions as children of $admin ...</span>
</code></pre>
<p>Note that in the above, because "author" is added as a child of "admin", when you implement the <code>execute()</code> method
of the rule class, you need to respect this hierarchy as well. That is why when the role name is "author",
the <code>execute()</code> method will return true if the user group is either 1 or 2 (meaning the user is in either "admin"
group or "author" group).</p>
<p>Next, configure <code>authManager</code> by listing the two roles in <a href="./yii-rbac-basemanager.html#$defaultRoles-detail">yii\rbac\BaseManager::$defaultRoles</a>:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">return</span> [
    <span class="hljs-comment">// ...</span>
    <span class="hljs-string">'components'</span> =&gt; [
        <span class="hljs-string">'authManager'</span> =&gt; [
            <span class="hljs-string">'class'</span> =&gt; <span class="hljs-string">'yii\rbac\PhpManager'</span>,
            <span class="hljs-string">'defaultRoles'</span> =&gt; [<span class="hljs-string">'admin'</span>, <span class="hljs-string">'author'</span>],
        ],
        <span class="hljs-comment">// ...</span>
    ],
];
</code></pre>
<p>Now if you perform an access check, both of the <code>admin</code> and <code>author</code> roles will be checked by evaluating
the rules associated with them. If the rule returns true, it means the role applies to the current user.
Based on the above rule implementation, this means if the <code>group</code> value of a user is 1, the <code>admin</code> role
would apply to the user; and if the <code>group</code> value is 2, the <code>author</code> role would apply.</p>
        <div class="toplink"><a href="#" class="h1" title="go to top"><span class="glyphicon glyphicon-arrow-up"></a></div>
    </div>
</div>


</div>

<footer class="footer">
        <p class="pull-right"><small>Page generated on Sat, 09 Jul 2016 12:16:31 +0000</small></p>
    Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a></footer>

<script type="text/javascript">jQuery(document).ready(function () {
    var shiftWindow = function () { scrollBy(0, -50) };
    if (location.hash) setTimeout(shiftWindow, 1);
    window.addEventListener("hashchange", shiftWindow);
var element = document.createElement("script");
element.src = "./jssearch.index.js";
document.body.appendChild(element);

var searchBox = $('#searchbox');

// search when typing in search field
searchBox.on("keyup", function(event) {
    var query = $(this).val();

    if (query == '' || event.which == 27) {
        $('#search-resultbox').hide();
        return;
    } else if (event.which == 13) {
        var selectedLink = $('#search-resultbox a.selected');
        if (selectedLink.length != 0) {
            document.location = selectedLink.attr('href');
            return;
        }
    } else if (event.which == 38 || event.which == 40) {
        $('#search-resultbox').show();

        var selected = $('#search-resultbox a.selected');
        if (selected.length == 0) {
            $('#search-results').find('a').first().addClass('selected');
        } else {
            var next;
            if (event.which == 40) {
                next = selected.parent().next().find('a').first();
            } else {
                next = selected.parent().prev().find('a').first();
            }
            if (next.length != 0) {
                var resultbox = $('#search-results');
                var position = next.position();

//              TODO scrolling is buggy and jumps around
//                resultbox.scrollTop(Math.floor(position.top));
//                console.log(position.top);

                selected.removeClass('selected');
                next.addClass('selected');
            }
        }

        return;
    }
    $('#search-resultbox').show();
    $('#search-results').html('<li><span class="no-results">No results</span></li>');

    var result = jssearch.search(query);

    if (result.length > 0) {
        var i = 0;
        var resHtml = '';

        for (var key in result) {
            if (i++ > 20) {
                break;
            }
            resHtml = resHtml +
            '<li><a href="' + result[key].file.u.substr(3) +'"><span class="title">' + result[key].file.t + '</span>' +
            '<span class="description">' + result[key].file.d + '</span></a></li>';
        }
        $('#search-results').html(resHtml);
    }
});

// hide the search results on ESC
$(document).on("keyup", function(event) { if (event.which == 27) { $('#search-resultbox').hide(); } });
// hide search results on click to document
$(document).bind('click', function (e) { $('#search-resultbox').hide(); });
// except the following:
searchBox.bind('click', function(e) { e.stopPropagation(); });
$('#search-resultbox').bind('click', function(e) { e.stopPropagation(); });

});</script></body>
</html>
